﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System.Windows.Input;
using VisionFrame.Base.Converter;
using VisionFrame.Base.Models;

namespace VisionFrame.Base
{
    // 解决序列化时多态对象的类型区分
    //[JsonPolymorphic(UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor)]
    //[JsonDerivedType(typeof(DecisionNodeModelBase), typeDiscriminator: "decision")]

    // 对这类对象进么Json序列的时候   会执行Converter中的相关方法
    [JsonConverter(typeof(NodeJsonConverter))]
    public class NodeModelBase : INotifyPropertyChanged
    {
        public string TypeInfo { get; set; }
        public List<int> FlowLevel { get; set; } = new List<int>();
        // 每个节点实例 唯一编号
        public string NodeId { get; set; }
        public NodeModelBase()
        {
            NodeId = Guid.NewGuid().ToString();
        }

        public string NodeName { get; set; }

        public string TargetNodeObject { get; set; }

        public bool IsStart { get; set; } = false;

        public bool IsDecision { get; set; } = false;

        private double _x;

        public double X
        {
            get { return _x; }
            set
            {
                _x = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(X)));
            }
        }
        private double _y;

        public double Y
        {
            get { return _y; }
            set
            {
                _y = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Y)));
            }
        }

        public double W { get; set; }
        public double H { get; set; }


        private bool _isSelected = false;

        public event PropertyChangedEventHandler? PropertyChanged;

        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                _isSelected = value;

                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsSelected)));
            }
        }
        private bool _isShowProperties;

        public bool IsShowProperties
        {
            get { return _isShowProperties; }
            set
            {
                if (!IsSelected) return;

                _isShowProperties = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsShowProperties)));
            }
        }


        private bool _isRunning;

        public bool IsRunning
        {
            get { return _isRunning; }
            set
            {
                _isRunning = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsRunning)));
            }
        }

        private long _duration;

        public long Duration
        {
            get { return _duration; }
            set
            {
                _duration = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Duration)));
            }
        }


        public List<NodeArgModel> Arguments { get; set; } = new List<NodeArgModel>();

        public bool ShowAnchorT { get; set; } = true;
        public bool ShowAnchorB { get; set; } = true;
        public bool ShowAnchorL { get; set; } = true;
        public bool ShowAnchorR { get; set; } = true;

        public void SetAnchorShow(string anchor, bool show)
        {
            PropertyInfo pi = this.GetType().GetProperty("ShowAnchor" + anchor);
            if (pi != null)
            {
                pi.SetValue(this, show);
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ShowAnchor" + anchor));
            }
        }



        //public List<>
        public virtual void Execute(IFlowContext flowContext) { }
    }
}
